/**
 * 设备判断工具函数 - TypeScript版本
 * 提供设备类型判断、屏幕尺寸检测、设备特性识别等功能
 * 支持直接复制粘贴使用，无需任何依赖
 * 每个函数都是独立的，可以单独复制使用
 */

// 类型定义
export interface DeviceInfo {
  type: string;
  isMobile: boolean;
  isTablet: boolean;
  isPC: boolean;
  isTV: boolean;
  isWatch: boolean;
  screenWidth: number;
  screenHeight: number;
  viewportWidth: number;
  viewportHeight: number;
  orientation: string;
  pixelRatio: number;
  userAgent: string;
  platform: string;
  isTouchDevice: boolean;
  isRetina: boolean;
  screenCategory: string;
}

export interface ScreenSize {
  category: string;
  width: number;
  height: number;
  isSmall: boolean;
  isMedium: boolean;
  isLarge: boolean;
  isExtraLarge: boolean;
}

export interface ViewportInfo {
  width: number;
  height: number;
  aspectRatio: number;
  isPortrait: boolean;
  isLandscape: boolean;
  density: number;
}

export interface BrowserInfo {
  userAgent: string;
  platform: string;
  language: string;
  cookieEnabled: boolean;
  onLine: boolean;
  isMobile: boolean;
  isDesktop: boolean;
}

export interface DeviceCapabilities {
  touch: boolean;
  multitouch: boolean;
  retina: boolean;
  orientation: boolean;
  fullscreen: boolean;
  geolocation: boolean;
  camera: boolean;
  vibration: boolean;
  webgl: boolean;
  webgl2: boolean;
  serviceWorker: boolean;
  pushNotification: boolean;
}

export interface AllDeviceInfo {
  device: DeviceInfo;
  screen: ScreenSize;
  viewport: ViewportInfo;
  browser: BrowserInfo;
  capabilities: DeviceCapabilities;
  responsive: {
    breakpoint: string;
    category: string;
  };
}

// 常量定义
export const DEVICE_TYPES = {
  PC: 'pc',
  TABLET: 'tablet',
  MOBILE: 'mobile',
  TV: 'tv',
  WATCH: 'watch',
  UNKNOWN: 'unknown'
} as const;

export const SCREEN_ORIENTATIONS = {
  PORTRAIT: 'portrait',
  LANDSCAPE: 'landscape'
} as const;

export const SCREEN_CATEGORIES = {
  XS: 'xs',    // < 576px
  SM: 'sm',    // 576px - 767px
  MD: 'md',    // 768px - 991px
  LG: 'lg',    // 992px - 1199px
  XL: 'xl',    // 1200px - 1399px
  XXL: 'xxl'   // >= 1400px
} as const;

/**
 * 获取设备类型
 * @returns {string} 设备类型
 */
export function getDeviceType(): string {
  const userAgent = navigator.userAgent.toLowerCase();
  const screenWidth = window.screen.width;
  const screenHeight = window.screen.height;
  
  // 智能手表检测
  if (screenWidth <= 200 && screenHeight <= 200) {
    return DEVICE_TYPES.WATCH;
  }
  
  // 电视检测
  if (screenWidth >= 1920 && screenHeight >= 1080 && 
      (userAgent.includes('tv') || userAgent.includes('smart-tv'))) {
    return DEVICE_TYPES.TV;
  }
  
  // 移动设备检测
  if (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent)) {
    // 平板检测
    if (screenWidth >= 768 && screenHeight >= 1024) {
      return DEVICE_TYPES.TABLET;
    }
    return DEVICE_TYPES.MOBILE;
  }
  
  // 默认PC
  return DEVICE_TYPES.PC;
}

/**
 * 检查是否为移动设备
 * @returns {boolean} 是否为移动设备
 */
export function isMobile(): boolean {
  return getDeviceType() === DEVICE_TYPES.MOBILE;
}

/**
 * 检查是否为平板设备
 * @returns {boolean} 是否为平板设备
 */
export function isTablet(): boolean {
  return getDeviceType() === DEVICE_TYPES.TABLET;
}

/**
 * 检查是否为PC设备
 * @returns {boolean} 是否为PC设备
 */
export function isPC(): boolean {
  return getDeviceType() === DEVICE_TYPES.PC;
}

/**
 * 检查是否为电视设备
 * @returns {boolean} 是否为电视设备
 */
export function isTV(): boolean {
  return getDeviceType() === DEVICE_TYPES.TV;
}

/**
 * 检查是否为智能手表
 * @returns {boolean} 是否为智能手表
 */
export function isWatch(): boolean {
  return getDeviceType() === DEVICE_TYPES.WATCH;
}

/**
 * 获取屏幕分类
 * @returns {string} 屏幕分类
 */
export function getScreenCategory(): string {
  const width = window.innerWidth || document.documentElement.clientWidth || window.screen.width;
  
  if (width < 576) return SCREEN_CATEGORIES.XS;
  if (width < 768) return SCREEN_CATEGORIES.SM;
  if (width < 992) return SCREEN_CATEGORIES.MD;
  if (width < 1200) return SCREEN_CATEGORIES.LG;
  if (width < 1400) return SCREEN_CATEGORIES.XL;
  return SCREEN_CATEGORIES.XXL;
}

/**
 * 检查是否为竖屏
 * @returns {boolean} 是否为竖屏
 */
export function isPortrait(): boolean {
  return window.innerHeight > window.innerWidth;
}

/**
 * 检查是否为横屏
 * @returns {boolean} 是否为横屏
 */
export function isLandscape(): boolean {
  return window.innerWidth > window.innerHeight;
}

/**
 * 检查是否为触摸设备
 * @returns {boolean} 是否为触摸设备
 */
export function isTouch(): boolean {
  return 'ontouchstart' in window || 
         navigator.maxTouchPoints > 0 || 
         navigator.msMaxTouchPoints > 0;
}

/**
 * 检查是否为Retina屏幕
 * @returns {boolean} 是否为Retina屏幕
 */
export function isRetina(): boolean {
  return window.devicePixelRatio > 1;
}

/**
 * 获取设备信息
 * @returns {DeviceInfo} 设备信息对象
 */
export function getDeviceInfo(): DeviceInfo {
  const type = getDeviceType();
  const screenWidth = window.screen.width;
  const screenHeight = window.screen.height;
  const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
  const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
  
  return {
    type,
    isMobile: isMobile(),
    isTablet: isTablet(),
    isPC: isPC(),
    isTV: isTV(),
    isWatch: isWatch(),
    screenWidth,
    screenHeight,
    viewportWidth,
    viewportHeight,
    orientation: isPortrait() ? SCREEN_ORIENTATIONS.PORTRAIT : SCREEN_ORIENTATIONS.LANDSCAPE,
    pixelRatio: window.devicePixelRatio || 1,
    userAgent: navigator.userAgent,
    platform: navigator.platform,
    isTouchDevice: isTouch(),
    isRetina: isRetina(),
    screenCategory: getScreenCategory()
  };
}

/**
 * 获取屏幕尺寸信息
 * @returns {ScreenSize} 屏幕尺寸信息
 */
export function getScreenSize(): ScreenSize {
  const width = window.innerWidth || document.documentElement.clientWidth || window.screen.width;
  const height = window.innerHeight || document.documentElement.clientHeight || window.screen.height;
  const category = getScreenCategory();
  
  return {
    category,
    width,
    height,
    isSmall: width < 768,
    isMedium: width >= 768 && width < 992,
    isLarge: width >= 992 && width < 1200,
    isExtraLarge: width >= 1200
  };
}

/**
 * 监听屏幕变化
 * @param {Function} callback - 回调函数
 * @returns {Function} 取消监听的函数
 */
export function onScreenChange(callback: (deviceInfo: DeviceInfo) => void): () => void {
  const handleResize = () => {
    callback(getDeviceInfo());
  };
  
  window.addEventListener('resize', handleResize);
  window.addEventListener('orientationchange', handleResize);
  
  // 返回取消监听的函数
  return () => {
    window.removeEventListener('resize', handleResize);
    window.removeEventListener('orientationchange', handleResize);
  };
}

/**
 * 监听设备类型变化
 * @param {Function} callback - 回调函数
 * @returns {Function} 取消监听的函数
 */
export function onDeviceTypeChange(callback: (deviceType: string, deviceInfo: DeviceInfo) => void): () => void {
  let lastDeviceType = getDeviceType();
  
  const handleChange = () => {
    const currentDeviceType = getDeviceType();
    if (currentDeviceType !== lastDeviceType) {
      lastDeviceType = currentDeviceType;
      callback(currentDeviceType, getDeviceInfo());
    }
  };
  
  window.addEventListener('resize', handleChange);
  window.addEventListener('orientationchange', handleChange);
  
  // 返回取消监听的函数
  return () => {
    window.removeEventListener('resize', handleChange);
    window.removeEventListener('orientationchange', handleChange);
  };
}

/**
 * 监听屏幕方向变化
 * @param {Function} callback - 回调函数
 * @returns {Function} 取消监听的函数
 */
export function onOrientationChange(callback: (orientation: string, deviceInfo: DeviceInfo) => void): () => void {
  let lastOrientation = isPortrait() ? SCREEN_ORIENTATIONS.PORTRAIT : SCREEN_ORIENTATIONS.LANDSCAPE;
  
  const handleChange = () => {
    const currentOrientation = isPortrait() ? SCREEN_ORIENTATIONS.PORTRAIT : SCREEN_ORIENTATIONS.LANDSCAPE;
    if (currentOrientation !== lastOrientation) {
      lastOrientation = currentOrientation;
      callback(currentOrientation, getDeviceInfo());
    }
  };
  
  window.addEventListener('resize', handleChange);
  window.addEventListener('orientationchange', handleChange);
  
  // 返回取消监听的函数
  return () => {
    window.removeEventListener('resize', handleChange);
    window.removeEventListener('orientationchange', handleChange);
  };
}

/**
 * 检查是否为小屏幕设备
 * @returns {boolean} 是否为小屏幕设备
 */
export function isSmallScreen(): boolean {
  const width = window.innerWidth || document.documentElement.clientWidth;
  return width < 768;
}

/**
 * 检查是否为中等屏幕设备
 * @returns {boolean} 是否为中等屏幕设备
 */
export function isMediumScreen(): boolean {
  const width = window.innerWidth || document.documentElement.clientWidth;
  return width >= 768 && width < 992;
}

/**
 * 检查是否为大屏幕设备
 * @returns {boolean} 是否为大屏幕设备
 */
export function isLargeScreen(): boolean {
  const width = window.innerWidth || document.documentElement.clientWidth;
  return width >= 992;
}

/**
 * 检查是否为超大屏幕设备
 * @returns {boolean} 是否为超大屏幕设备
 */
export function isExtraLargeScreen(): boolean {
  const width = window.innerWidth || document.documentElement.clientWidth;
  return width >= 1200;
}

/**
 * 获取视口信息
 * @returns {ViewportInfo} 视口信息
 */
export function getViewportInfo(): ViewportInfo {
  const width = window.innerWidth || document.documentElement.clientWidth;
  const height = window.innerHeight || document.documentElement.clientHeight;
  
  return {
    width,
    height,
    aspectRatio: width / height,
    isPortrait: height > width,
    isLandscape: width > height,
    density: window.devicePixelRatio || 1
  };
}

/**
 * 检查是否支持触摸
 * @returns {boolean} 是否支持触摸
 */
export function supportsTouch(): boolean {
  return isTouch();
}

/**
 * 检查是否支持多点触控
 * @returns {boolean} 是否支持多点触控
 */
export function supportsMultiTouch(): boolean {
  return navigator.maxTouchPoints > 1;
}

/**
 * 获取设备像素比
 * @returns {number} 设备像素比
 */
export function getPixelRatio(): number {
  return window.devicePixelRatio || 1;
}

/**
 * 检查是否为高分辨率屏幕
 * @returns {boolean} 是否为高分辨率屏幕
 */
export function isHighResolution(): boolean {
  return getPixelRatio() > 1;
}

/**
 * 获取屏幕密度
 * @returns {string} 屏幕密度分类
 */
export function getScreenDensity(): string {
  const ratio = getPixelRatio();
  
  if (ratio <= 1) return 'standard';
  if (ratio <= 1.5) return 'high';
  if (ratio <= 2) return 'retina';
  return 'ultra';
}

/**
 * 检查是否为移动端浏览器
 * @returns {boolean} 是否为移动端浏览器
 */
export function isMobileBrowser(): boolean {
  const userAgent = navigator.userAgent.toLowerCase();
  return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
}

/**
 * 检查是否为桌面端浏览器
 * @returns {boolean} 是否为桌面端浏览器
 */
export function isDesktopBrowser(): boolean {
  return !isMobileBrowser();
}

/**
 * 获取浏览器信息
 * @returns {BrowserInfo} 浏览器信息
 */
export function getBrowserInfo(): BrowserInfo {
  const userAgent = navigator.userAgent;
  
  return {
    userAgent,
    platform: navigator.platform,
    language: navigator.language,
    cookieEnabled: navigator.cookieEnabled,
    onLine: navigator.onLine,
    isMobile: isMobileBrowser(),
    isDesktop: isDesktopBrowser()
  };
}

/**
 * 检查是否支持特定功能
 * @param {string} feature - 功能名称
 * @returns {boolean} 是否支持
 */
export function supportsFeature(feature: string): boolean {
  switch (feature) {
    case 'touch':
      return isTouch();
    case 'retina':
      return isRetina();
    case 'multitouch':
      return supportsMultiTouch();
    case 'orientation':
      return 'orientation' in window;
    case 'fullscreen':
      return !!(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled);
    case 'geolocation':
      return 'geolocation' in navigator;
    case 'camera':
      return 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices;
    case 'vibration':
      return 'vibrate' in navigator;
    default:
      return false;
  }
}

/**
 * 获取设备能力信息
 * @returns {DeviceCapabilities} 设备能力信息
 */
export function getDeviceCapabilities(): DeviceCapabilities {
  return {
    touch: isTouch(),
    multitouch: supportsMultiTouch(),
    retina: isRetina(),
    orientation: 'orientation' in window,
    fullscreen: !!(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled),
    geolocation: 'geolocation' in navigator,
    camera: 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices,
    vibration: 'vibrate' in navigator,
    webgl: !!window.WebGLRenderingContext,
    webgl2: !!window.WebGL2RenderingContext,
    serviceWorker: 'serviceWorker' in navigator,
    pushNotification: 'PushManager' in window
  };
}

/**
 * 检查是否为特定设备
 * @param {string} deviceType - 设备类型
 * @returns {boolean} 是否为指定设备
 */
export function isDevice(deviceType: string): boolean {
  return getDeviceType() === deviceType;
}

/**
 * 检查屏幕尺寸是否在指定范围内
 * @param {number} minWidth - 最小宽度
 * @param {number} maxWidth - 最大宽度
 * @returns {boolean} 是否在范围内
 */
export function isScreenSizeInRange(minWidth: number, maxWidth: number): boolean {
  const width = window.innerWidth || document.documentElement.clientWidth;
  return width >= minWidth && width <= maxWidth;
}

/**
 * 获取响应式断点
 * @returns {string} 当前断点
 */
export function getResponsiveBreakpoint(): string {
  const width = window.innerWidth || document.documentElement.clientWidth;
  
  if (width < 576) return 'xs';
  if (width < 768) return 'sm';
  if (width < 992) return 'md';
  if (width < 1200) return 'lg';
  if (width < 1400) return 'xl';
  return 'xxl';
}

/**
 * 检查是否匹配媒体查询
 * @param {string} mediaQuery - 媒体查询字符串
 * @returns {boolean} 是否匹配
 */
export function matchesMediaQuery(mediaQuery: string): boolean {
  return window.matchMedia(mediaQuery).matches;
}

/**
 * 监听媒体查询变化
 * @param {string} mediaQuery - 媒体查询字符串
 * @param {Function} callback - 回调函数
 * @returns {Function} 取消监听的函数
 */
export function onMediaQueryChange(mediaQuery: string, callback: (matches: boolean, mediaQueryList: MediaQueryList) => void): () => void {
  const mediaQueryList = window.matchMedia(mediaQuery);
  
  const handleChange = (e: MediaQueryListEvent) => {
    callback(e.matches, mediaQueryList);
  };
  
  // 现代浏览器
  if (mediaQueryList.addEventListener) {
    mediaQueryList.addEventListener('change', handleChange);
    return () => mediaQueryList.removeEventListener('change', handleChange);
  }
  // 旧版浏览器
  else if (mediaQueryList.addListener) {
    mediaQueryList.addListener(handleChange);
    return () => mediaQueryList.removeListener(handleChange);
  }
  
  return () => {};
}

/**
 * 获取所有设备信息
 * @returns {AllDeviceInfo} 完整的设备信息
 */
export function getAllDeviceInfo(): AllDeviceInfo {
  return {
    device: getDeviceInfo(),
    screen: getScreenSize(),
    viewport: getViewportInfo(),
    browser: getBrowserInfo(),
    capabilities: getDeviceCapabilities(),
    responsive: {
      breakpoint: getResponsiveBreakpoint(),
      category: getScreenCategory()
    }
  };
}